package com.maicss.coursedesign.dao;

import com.maicss.coursedesign.types.InvitationCode;
import com.maicss.coursedesign.types.User;

import java.sql.*;
import java.util.Random;


public class UserDao {
    /**
     * 通过邀请码字符串获取邀请码对象，包括所有者和使用者ID。
     * @param invitationCode 邀请码
     * @return 返回InvitationCode对象，若不存在则返回null
     */
    private static InvitationCode FindInvitationCode(String invitationCode) throws SQLException {
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement;
        String sql = "select * from invitation_code where CODE=?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1,invitationCode);
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()){
            return new InvitationCode(
                    resultSet.getInt("OWNER"),
                    resultSet.getString("CODE"),
                    resultSet.getInt("USER")
            );
        }else {
            return null;
        }
    }

    /**
     * 生成随机的六位字符串，包括大写字母和数字。
     * @return 返回一个六位随机字符串
     */
    private static String makeNewInvitationCode(){
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<6;i++){
            int number=random.nextInt(str.length());
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 创建一个对应用户的邀请码，该用户可将邀请码给予任何人用于注册本系统，当该
     * 用户存在一个未使用的邀请码时，本方法将返回这个已经存在的邀请码，且并不会
     * 创建任何新的邀请码。
     * @param id 邀请码的所属用户。
     * @return 返回生成的或者找到的邀请码。
     */
    public static String CreateInvitationCode(int id) throws SQLException {
        // 检查是否有尚未使用的激活码
        {
            Connection connection = DBConnect.getConnection();
            PreparedStatement preparedStatement = null;
            String sql = "select * from invitation_code where OWNER=? and USER=-1;";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,id);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                return resultSet.getString("CODE");
            }
        }
        String code;
        do{
            code = makeNewInvitationCode();
        }while (FindInvitationCode(code)!=null);
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        String sql = "insert into invitation_code(OWNER, CODE, USER) VALUES (?,?,-1)";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,id);
        preparedStatement.setString(2,code);
        int res = preparedStatement.executeUpdate();
        connection.close();
        preparedStatement.close();
        return code;
    }

    /**
     * 根据用户名获得用户对象
     * @param name 用户名
     * @return 用户对象
     */
    public static User GetUserByName(String name){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement;
        if (connection == null){
            return null;
        }
        String sql = "select * from user_list where USER_NAME=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                return new User(resultSet.getInt("USER_ID"),
                        resultSet.getString("USER_NAME"),
                        resultSet.getString("USER_PWD"),
                        resultSet.getInt("USER_HEAD"));
            }else {
                return null;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据用户ID获得用户对象
     * @param id 用户ID
     * @return 用户对象
     */
    public static User GetUserByID(int id){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement;
        if (connection == null){
            return null;
        }
        String sql = "select * from user_list where USER_ID=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,id);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                return new User(resultSet.getInt("USER_ID"),
                        resultSet.getString("USER_NAME"),
                        resultSet.getString("USER_PWD"),
                        resultSet.getInt("USER_HEAD"));
            }else {
                return null;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 用户注册，需要传入合法的邀请码，否则失败。
     * @param name 注册的用户名
     * @param pwd 注册的密码
     * @param invitationCode 邀请码
     * @return 返回注册是否成功
     */
    public static boolean UserRegister(String name, String pwd, String invitationCode){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null){
            return false;
        }

        String sql = "insert into user_list(USER_NAME, USER_PWD) VALUES (?,?)";
        try {
            InvitationCode code = FindInvitationCode(invitationCode);
            if (code == null){
                // 提供的邀请码不存在
                return false;
            }
            if (code.getUser()>0){
                // 该邀请码已被使用
                return false;
            }
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,pwd);
            int res = preparedStatement.executeUpdate();

            sql = "update invitation_code set USER=? WHERE CODE=?;";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,GetUserByName(name).getId());
            preparedStatement.setString(2,code.getCode());
            res = preparedStatement.executeUpdate();

            connection.close();
            preparedStatement.close();
            return res > 0;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 用户账户密码检查，用于登录模块
     * @param name 用户名
     * @param pwd 密码
     * @return 返回是否合法。
     */
    public static boolean UserCheck(String name, String pwd){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null){
            return false;
        }
        String sql = "select * from user_list where USER_NAME=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                String relPwd = resultSet.getString("USER_PWD");
                if (relPwd == null){
                    return false;
                }else {
                    return relPwd.equals(pwd);
                }
            }else {
                return false;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据用户ID修改用户密码
     * @param id 用户ID
     * @param newPwd 用户密码
     * @return 返回是否修改成功
     */
    public static boolean ChangePassword(int id, String newPwd){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null){
            return false;
        }
        String sql = "update user_list set USER_PWD=? where USER_ID=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,newPwd);
            preparedStatement.setInt(2,id);
            int res = preparedStatement.executeUpdate();
            return res == 1;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过ID修改用户名
     * @param id 要修改用户的ID
     * @param newName 要修改用户的新用户名
     * @return 返回是否修改成功
     */
    public static boolean ChangeUserName(int id, String newName){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null){
            return false;
        }
        String sql = "update user_list set USER_NAME=? where USER_ID=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,newName);
            preparedStatement.setInt(2,id);
            int res = preparedStatement.executeUpdate();
            return res == 1;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过ID修改头像代号
     * @param id 用户ID
     * @param head 头像号
     * @return 返回是否修改成功
     */
    public static  boolean ChangeUserHead(int id, int head) {
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null){
            return false;
        }
        String sql = "update user_list set USER_HEAD=? where USER_ID=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,head);
            preparedStatement.setInt(2,id);
            int res = preparedStatement.executeUpdate();
            return res == 1;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过用户名删除用户
     * @param userName 要删除的用户的用户名
     * @return 返回删除是否成功
     */
    public static boolean deleteUser(String userName){
        Connection connection = DBConnect.getConnection();
        PreparedStatement preparedStatement = null;
        if (connection==null) {
            return false;
        }
        String sql="delete from user_list where USER_NAME=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,userName);
            int res = preparedStatement.executeUpdate();
            return res == 1;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }
}
